package example.lesson07_01;

// 对象转型 | 引用类型转换
public class TestCasting {

    static Person getPerson(boolean isStudent) {
        if(isStudent) {
            return new Student(20, "ZhangSan", "zsc");
        } else {
            return new Person(20, "ZhangSan");
        }
    }

    public static void main(String[] args) {
//        double d = 10;  // int -> double， 自动转换
//        int i = (int)3.14;  // double -> int，强制转换

        // 向上转型， 将子类引用的值 赋给 父类引用变量， 父类引用 指向 子类对象
        // 对象的类型是不会发生改变的
        // 安全的，可以自动转换
        // Student s = new Student(20, "ZhangSan", "zsc");
        // Person p = s;  // Student -> Person
        // 语义上理解： p 是“可以”指向 Person 的指针， 自然就可以指向 Student， 因为 Student is Person
        Person p = new Student(20, "ZhangSan", "zsc");
        System.out.println(p);

        // 向下转型， 将父类引用的值 赋给 子类引用变量
        // 需要强制转换, 并且只有当 父类引用 实际指向 子类对象 时，才能转换成功，否则会报 类型转换 异常
        // p = new Person(20, "LiSi");
        // 向下转型是 不安全的， 转型之前 可以 先做类型检测
        // 如果 p 指向的对象是 Student 或其子类的对象，返回true， 否则返回 false
        // Math.random() 返回一个 [0,1) 之间的随机小数
        Person obj = getPerson(Math.random() > 0.5);
        if(obj instanceof Student) {
            Student s = (Student)obj;
            System.out.println(s);
        } else {
            System.out.println("无法转型");
        }

    }
}

class Person {
    public int age;
    public String name;
    Person(int age, String name) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "age:" + age + ", name:" + name;
    }
}

class Student extends Person {
    public String school;
    Student(int age, String name, String school) {
        super(age, name);
        this.school = school;
    }
    @Override
    public String toString() {
        return super.toString() + ",school:" + school;
    }
}
